package com.ruoyi.rsikManage.service.Impl;

import com.ruoyi.common.GenericMethodsService;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.rsikManage.domain.*;
import com.ruoyi.rsikManage.domain.vo.*;
import com.ruoyi.rsikManage.mapper.MonitorPointMapper;
import com.ruoyi.rsikManage.mapper.TVcrDataMapper;
import com.ruoyi.rsikManage.service.MonitorPointService;
import com.ruoyi.rsikManage.service.VideoResourceTreeService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.NumberFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MonitorPointServiceImpl implements MonitorPointService {


    @Value("${video.manufacturer_name}")
    private String VIDEO_MANUFACTURER_NAME;
    @Autowired
    private MonitorPointMapper monitorPointMapper;

    @Autowired
    private TVcrDataMapper tVcrDataMapper;
    @Autowired
    private TVideoStandPlaceServiceImpl tVideoStandPlaceService;
    @Autowired
    private VideoResourceTreeService videoResourceTreeService;
    @Autowired
    private GenericMethodsService genericMethodsService;

    @Override
    public List<MonitorPoint> selectMonitorPointsInPlace(Long placeId) {
        return monitorPointMapper.selectMonitorPointsInPlace(placeId);
    }

    @Override
    public List<MonitorPoint> selectMonitorsDetail(MonitorPoint monitorPoint, VideoResourceTreeNode treeNode) {
        List<MonitorPoint> monitorPoints = monitorPointMapper.selectMonitorsDetail(monitorPoint, treeNode);
        Map<Long, SysDept> deptMap = genericMethodsService.getDeptMap();
        // 遍历 reportApprovals 列表，根据 unitCode 匹配 deptName 并赋值给 unitName
        for (MonitorPoint mp : monitorPoints) {
            SysDept dept = deptMap.get(mp.getUnitCode());
            if (dept != null) {
                mp.setUnitName(dept.getDeptName());
            }
        }
        return monitorPoints;
    }

    @Override
    public List<MonitorPoint> selectMonitorsDetailForUnitCodes(MonitorPoint monitorPoint) {
        List<MonitorPoint> monitorPoints = monitorPointMapper.selectMonitorsDetailForUnitCodes(monitorPoint );
        Map<Long, SysDept> deptMap = genericMethodsService.getDeptMap();
        // 遍历 reportApprovals 列表，根据 unitCode 匹配 deptName 并赋值给 unitName
        for (MonitorPoint mp : monitorPoints) {
            SysDept dept = deptMap.get(mp.getUnitCode());
            if (dept != null) {
                mp.setUnitName(dept.getDeptName());
            }
        }
        return monitorPoints;
    }

    @Override
    public MonitorPoint selectMonitorByApeId(String apeId) {
        return monitorPointMapper.selectMonitorByApeId(apeId);
    }

    @Override
    public List<MonitorPoint> selectAllMonitorPoints() {
        return monitorPointMapper.selectAllMonitorPoints();
    }

    @Override
    public List<MonitorPoint> selectAllMonitorPointsGroup(Long unitCode) {
        return monitorPointMapper.selectAllMonitorPointsGroup(unitCode);
    }

    @Override
    public List<MonitorPoint> selectMonitorPoints(String monitorName) {
        return monitorPointMapper.selectMonitorPoints(monitorName);
    }

    @Override
    public List<MonitorPointDiagnosisResultVo> selectMonitorsDiagnosisResult(String treeType, Integer resourceTreeNodeId, String diagnosisResult, Date diagnosisStartTime, Date diagnosisEndTime, String monitorPointName) {
        return monitorPointMapper.selectMonitorsDiagnosisResult(treeType, resourceTreeNodeId, diagnosisResult, diagnosisStartTime, diagnosisEndTime, monitorPointName);
    }

        @Override
        public List<CoalMine> selectCoalMinesWithMonitors(String monitorName) {
            List<CoalMine> coalMines = monitorPointMapper.selectCoalMinesWithMonitors(monitorName);
            if(VIDEO_MANUFACTURER_NAME.equals("海康")){
                System.out.println(VIDEO_MANUFACTURER_NAME);
                for (CoalMine recorder :coalMines){
                    String coalMineName = recorder.getCoalMineName();
                    TVcrData tVcrData = new TVcrData();
                    tVcrData.setVcrName(coalMineName);
                    TVcrData tVcrData1 = tVcrDataMapper.selectTVcrDataList(tVcrData).get(0);
                    recorder.setIp(tVcrData1.getVcrIp());
                    recorder.setPort(tVcrData1.getVcrPort());
                    recorder.setUserName(tVcrData1.getVcrUsername());
                    recorder.setPassword(tVcrData1.getVcrPassword());
                    recorder.setType(tVcrData1.getVcrType());
                    List<MonitorPoint> monitorPointList = recorder.getMonitorPointList();
                    for (MonitorPoint monitorPoint : monitorPointList) {
                        monitorPoint.setOwnerApsIp(tVcrData1.getVcrIp());
                    }
                }
            }



            return coalMines;
        }

    @Override
    public List<CoalMine> selectCoalMinesWithMonitorsForUnitCodes(Long unitCode,String monitorName,String isOnline,List<Long> unitCodes) {
        List<CoalMine> coalMines = monitorPointMapper.selectCoalMinesWithMonitorsForUnitCodes(unitCode,monitorName,isOnline,unitCodes);
        if(VIDEO_MANUFACTURER_NAME.equals("海康")){
            for (CoalMine recorder :coalMines){
                String coalMineName = recorder.getCoalMineName();
                TVcrData tVcrData = new TVcrData();
                tVcrData.setVcrName(coalMineName);
                TVcrData tVcrData1 = tVcrDataMapper.selectTVcrDataList(tVcrData).get(0);
                recorder.setIp(tVcrData1.getVcrIp());
                recorder.setPort(tVcrData1.getVcrPort());
                recorder.setUserName(tVcrData1.getVcrUsername());
                recorder.setPassword(tVcrData1.getVcrPassword());
                recorder.setType(tVcrData1.getVcrType());
                List<MonitorPoint> monitorPointList = recorder.getMonitorPointList();
                for (MonitorPoint monitorPoint : monitorPointList) {
                    monitorPoint.setOwnerApsIp(tVcrData1.getVcrIp());
                }
            }
        }
        return coalMines;
    }


    @Override
    public int deleteTheTreeNodeAndAllMonitorsRel(Integer nodeId) {
        return monitorPointMapper.deleteTheTreeNodeAndAllMonitorsRel(nodeId);
    }


    @Override
    public int delMonitorAndTreeNodeRelInTheTreeType(String monitorId, String treeType) {
        List<VideoResourceTreeNode> TreeNodes = videoResourceTreeService.selectTreeByTreeType(treeType);
        HashSet<Integer> nodeIdSet = new HashSet<>();
        for (VideoResourceTreeNode treeNode: TreeNodes) {
            nodeIdSet.add(treeNode.getNodeId());
        }
        return monitorPointMapper.delMonitorAndNodeRelInTheIdSet(monitorId, nodeIdSet);
    }


    @Override
    public Integer selectOfflineTimeOutMinutes() {
        return monitorPointMapper.selectOfflineTimeOutMinutes();
    }

    @Override
    public MonitorsOfflineAlarmSettings selectMonitorOfflineAlarmSettings() {
        return monitorPointMapper.selectMonitorOfflineAlarmSettings();
    }

    @Override
    public int updateMonitorOfflineAlarmSettings(MonitorsOfflineAlarmSettings monitorOfflineAlarmSettings) {
        return monitorPointMapper.updateMonitorOfflineAlarmSettings(monitorOfflineAlarmSettings);
    }

    @Override
    public List<MonitorPoint> selectMonitorsThatNeedToSendOfflineAlarm() {
        return monitorPointMapper.selectMonitorsThatNeedToSendOfflineAlarm();
    }

    @Override
    public List<MonitorPoint> selectMonitorsOfflineTimeoutList() {
        return monitorPointMapper.selectMonitorsOfflineTimeoutList();
    }

    @Override
    public int insertMonitorOfflineAlarm(List<MonitorPoint> monitorListThatOfflineTimeout) {
        return monitorPointMapper.insertMonitorOfflineAlarm(monitorListThatOfflineTimeout);

    }

    @Override
    public int insertMonitorOfflineAlarmForUnitCodes(List<MonitorPoint> monitorListThatOfflineTimeout) {
        return monitorPointMapper.insertMonitorOfflineAlarmForUnitCodes(monitorListThatOfflineTimeout);

    }

    @Override
    public int updateAlarmStatusAsSent(List<MonitorPoint> monitorListThatOfflineTimeout) {
        return monitorPointMapper.updateAlarmStatusAsSent(monitorListThatOfflineTimeout);
    }

    @Override
    public int updateAlarmStatusAsSentForUnitCodes(List<MonitorPoint> monitorListThatOfflineTimeout) {
        return monitorPointMapper.updateAlarmStatusAsSentForUnitCodes(monitorListThatOfflineTimeout);
    }

    @Override
    public void deleteMonitorNotInList(List<MonitorPoint> list) {
        monitorPointMapper.deleteMonitorNotInList(list);
    }



    @Override
    public HashMap<String, MonitorPoint> selectMonitorMapByList(List<String> monitorIdList) {
        return monitorPointMapper.selectMonitorMapByList(monitorIdList);
    }



    @Override
    public HashMap<String, Integer> selectTotalMonitorCountAndOnlineMonitorCount() {
        return monitorPointMapper.selectTotalMonitorCountAndOnlineMonitorCount();
    }

    @Override
    public HashMap<String, Integer> selectMonitorStatusCount(Long unitCode,List<Long> unitCodes) {
        return monitorPointMapper.selectMonitorStatusCount(unitCode,unitCodes);
    }

    @Override
    public HashMap<String, Integer> selectTotalMonitorCountAndOnlineMonitorCountForUnitCodes(List<String> apeIds,List<Long> unitCods) {
        return monitorPointMapper.selectTotalMonitorCountAndOnlineMonitorCountForUnitCodes(apeIds,unitCods);
    }

    @Override
    public int updateMonitorStatus(MonitorPoint monitor) {
        return monitorPointMapper.updateMonitorStatus(monitor);
    }

    @Override
    public List<HistogramVo> selectCameraTypeWithMonitorNumber() {
        return monitorPointMapper.selectCameraTypeWithMonitorNumber();
    }

    @Override
    public List<HistogramVo> selectCameraTypeWithMonitorNumberForUnitCodes(List<Long> unitCodes) {
        return monitorPointMapper.selectCameraTypeWithMonitorNumberForUnitCodes(unitCodes);
    }

    @Override
    public RatioVo countOnlineRate() {
        RatioVo ratioVo = new RatioVo();
        List<HistogramVo> resList = new ArrayList<>();
        HistogramVo onLineVo = new HistogramVo();
        onLineVo.setX_axis("在线数");
        onLineVo.setY_axis(monitorPointMapper.countMonitorByIsOnline("1"));
        HistogramVo offLineVo = new HistogramVo();
        offLineVo.setX_axis("离线数");
        offLineVo.setY_axis(monitorPointMapper.countMonitorByIsOnline("2"));
        resList.add(onLineVo);
        resList.add(offLineVo);
        //
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2);
        String ratio = percentFormat.format((double) onLineVo.getY_axis() / (onLineVo.getY_axis() + offLineVo.getY_axis()));
        ratioVo.setValue(ratio);
        ratioVo.setData(resList);
        ratioVo.setDesc("实时更新，\n" +
                "在线率 = 在线数 / (离线数 + 在线数) * 100%");
        return ratioVo;
    }

    @Override
    public RatioVo countOnlineRateForUnitCodes(List<Long> unitCodes) {
        RatioVo ratioVo = new RatioVo();
        List<HistogramVo> resList = new ArrayList<>();
        HistogramVo onLineVo = new HistogramVo();
        onLineVo.setX_axis("在线数");
        int isOnlineCount= monitorPointMapper.countMonitorByIsOnlineForUnitCodes("1", unitCodes);
        onLineVo.setY_axis(isOnlineCount);
        HistogramVo offLineVo = new HistogramVo();
        offLineVo.setX_axis("离线数");
        int isNotOnlineCount = monitorPointMapper.countMonitorByIsOnlineForUnitCodes("2", unitCodes);
        offLineVo.setY_axis(isNotOnlineCount);
        resList.add(onLineVo);
        resList.add(offLineVo);
        //
        NumberFormat percentFormat = NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2);
        int sum = onLineVo.getY_axis() + offLineVo.getY_axis();
        String ratio="";
        if (sum != 0 ){
            ratio = percentFormat.format((double) onLineVo.getY_axis() / (onLineVo.getY_axis() + offLineVo.getY_axis()));
        } else {
            ratio = "0";
        }

        ratioVo.setValue(ratio);
        ratioVo.setData(resList);
        ratioVo.setDesc("实时更新，\n" +
                "在线率 = 在线数 / (离线数 + 在线数) * 100%");
        return ratioVo;
    }
    @Override
    public int addMonitorAndTreeNodeRel(String monitorId,Integer nodeId) {
        return monitorPointMapper.addMonitorAndTreeNodeRel(monitorId, nodeId);
    }

    @Override
    public int updateOfflineTimeOutMinutes(Integer setMinutes) {
        return monitorPointMapper.updateOfflineTimeOutMinutes(setMinutes);
    }

    @Override
    public List<MonitorPointVO> selectAllMonitors() {
        return monitorPointMapper.selectAllMonitors();
    }

    @Override
    public List<MonitorPointVO> selectAllMonitorsForUnitCodes(MonitorPoint monitorPoint) {
        return monitorPointMapper.selectAllMonitorsForUnitCodes(monitorPoint);
    }



    @Override
    public List<GisMonitorsVo> selectAllGisMonitors(GisMonitorsVo gisMonitorsVo) {
        return monitorPointMapper.selectAllGisMonitors(gisMonitorsVo);
    }

    @Override
    public List<GisMonitorsVo> gisMonitorsHasCoordinates() {
        return monitorPointMapper.gisMonitorsHasCoordinates();
    }

    @Override
    public void updateGisMonitorsCoordinates(GisMonitorsVo gisMonitorsVo) {
        monitorPointMapper.updateGisMonitorsCoordinates(gisMonitorsVo);
    }

    @Override
    public List<MonitorPoint> selectMonitorsThatDropLine() {
        return monitorPointMapper.selectMonitorsThatDropLine();
    }

    @Override
    public List<MonitorPoint> selectMonitorsThatDropLineForUnitCodes() {
        return monitorPointMapper.selectMonitorsThatDropLineForUnitCodes();
    }

    @Override
    public void recordDropLineMonitorList(List<MonitorPoint> dropLineMonitors) {
        if (dropLineMonitors.size()>0){
            monitorPointMapper.recordDropLineMonitorList(dropLineMonitors);
        }
    }

    @Override
    public void recordDropLineMonitorListForUnitCodes(List<MonitorPoint> dropLineMonitors) {
        if (dropLineMonitors.isEmpty()) {
            return;
        }else {
            // 获取当前小时的开始时间和结束时间
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime hourStart = now.truncatedTo(ChronoUnit.HOURS);
            LocalDateTime hourEnd = hourStart.plusHours(1);

            // 过滤掉当前小时内已存在的记录
            List<MonitorPoint> filteredMonitors = dropLineMonitors.stream()
                    .filter(monitorPoint -> !existsInCurrentHour(hourStart, hourEnd, monitorPoint.getUnitCode(), monitorPoint.getApeId()))
                    .collect(Collectors.toList());

            // 如果过滤后有需要插入的数据，则执行插入操作
            if (!filteredMonitors.isEmpty()) {
                monitorPointMapper.recordDropLineMonitorListForUnitCodes(filteredMonitors);
            }

        }


    }

    private boolean existsInCurrentHour(LocalDateTime startTime, LocalDateTime endTime, Long unitCode, String monitorId) {
        return monitorPointMapper.existsInCurrentHour(startTime, endTime, unitCode, monitorId);
    }

    @Override
    public List<GisMonitors3DVo> gisMonitorsHas3DCoordinates() {
        return monitorPointMapper.gisMonitorsHas3DCoordinates();
    }

    @Override
    public void updateMonitors3DCoordinates(GisMonitors3DVo gisMonitors3DVo) {
        monitorPointMapper.updateMonitors3DCoordinates(gisMonitors3DVo);
    }

    @Override
    public List<GisMonitors3DVo> selectAllMonitors3D(GisMonitors3DVo gisMonitors3DVo) {
        return monitorPointMapper.selectAllMonitors3D(gisMonitors3DVo);
    }

    @Override
    public List<MonitorOfflineAlarmSettingRespVo> selectMonitorsOfflineAlarmSettingTime(MonitorOfflineAlarmSettingRespVo monitorOfflineAlarmSettingVo) {
        return monitorPointMapper.selectMonitorsOfflineAlarmSettingTime(monitorOfflineAlarmSettingVo);
    }

    @Override
    public void updateOfflineAlarmSettingTime(MonitorOfflineAlarmSettingResqVo monitorOfflineAlarmSettingResqVo) {
        monitorPointMapper.updateOfflineAlarmSettingTime(monitorOfflineAlarmSettingResqVo);
    }


    @Override
    public int mergeMonitorListToMonitorTable(List<MonitorPoint> monitorPointList) {
        return monitorPointMapper.mergeMonitorListToMonitorTable(monitorPointList);
    }

    @Override
    public List<MonitorPoint> selectAllMonitorPoints2(MonitorPoint monitorPoint) {
        return monitorPointMapper.selectAllMonitorPoints2(monitorPoint);
    }



//    @Override
//    public RatioVo countComplianceRatio() {
//        RatioVo ratioVo = new RatioVo();
//        List<HistogramVo> resList = new ArrayList<>();
//        //
//        HistogramVo histogramVo1 = new HistogramVo();
//        histogramVo1.setX_axis("达标");
//        histogramVo1.setY_axis(monitorPointMapper.countMonitorByDiagnosisResult("1"));
//        //
//        HistogramVo histogramVo2 = new HistogramVo();
//        histogramVo2.setX_axis("一般");
//        histogramVo2.setY_axis(monitorPointMapper.countMonitorByDiagnosisResult("2"));
//        //
//        HistogramVo histogramVo3 = new HistogramVo();
//        histogramVo3.setX_axis("很差");
//        histogramVo3.setY_axis(monitorPointMapper.countMonitorByDiagnosisResult("3"));
//        //
//        HistogramVo histogramVo4 = new HistogramVo();
//        histogramVo4.setX_axis("失败");
//        histogramVo4.setY_axis(monitorPointMapper.countMonitorByDiagnosisResult("4"));
//        //
//        resList.add(histogramVo1);
//        resList.add(histogramVo2);
//        resList.add(histogramVo3);
//        resList.add(histogramVo4);
//        //
//        NumberFormat percentFormat = NumberFormat.getPercentInstance();
//        percentFormat.setMaximumFractionDigits(2);
//        String ratio = percentFormat.format((double)histogramVo1.getY_axis() / (histogramVo1.getY_axis() + histogramVo2.getY_axis() + histogramVo3.getY_axis() + histogramVo4.getY_axis()));
//
//        ratioVo.setValue(ratio);
//        ratioVo.setData(resList);
//        ratioVo.setDesc("实时获取最后一次的诊断结果，\n" +
//                "达标率 = 达标数 / (达标数 + 一般数 + 很差数 + 失败数) * 100%\n" +
//                "\n" +
//                "达标：实时获取最后一次的诊断的达标结果\n" +
//                "一般：实时获取最后一次的诊断的一般结果\n" +
//                "很差：实时获取最后一次的诊断的很差结果\n" +
//                "失败：实时获取最后一次的诊断的失败结果");
//        return ratioVo;
//    }
//    @Override
//    public int insertMonitorPoint(MonitorPoint monitor) {
//        return monitorPointMapper.insertMonitorPoint(monitor);
//    }
//
//    @Override
//    public int insertMonitorOfflineRecord(String monitorId, Date offlineTime) {
//        return monitorPointMapper.insertMonitorOfflineRecord(monitorId, offlineTime);
//    }
//
//    @Override
//    public int deleteMonitorByApeId(String monitorId) {
//        return monitorPointMapper.deleteMonitorByApeId(monitorId);
//    }
    //    @Override
//    public List<CoalMine> selectCoalMines() {
//        return monitorPointMapper.selectCoalMines();
//    }
//
//    @Override
//    public List<MonitorPoint> selectMonitorsInCoalMine(String coalMineName) {
//        return monitorPointMapper.selectMonitorsInCoalMine(coalMineName);
//    }
//
//    @Override
//    public Integer countOnlineMonitorInCoalMine(String coalMineName) {
//        return monitorPointMapper.countOnlineMonitorInCoalMine(coalMineName);
//    }

//
//    @Override
//    public void addMonitorAndPlaceRel(String monitorId, Long standPlaceId) {
//        TVideoStandPlace place = tVideoStandPlaceService.selectTVideoStandPlaceById(standPlaceId);
//        tVideoStandPlaceService.addMonitorRelPlace(place.getAddress(), monitorId);
//    }
//    @Override
//    public HashMap<String, MonitorPoint> selectAllMonitorMap() {
//        List<MonitorPoint> monitorPointList = selectAllMonitorPoints();
//        HashMap<String, MonitorPoint> monitorMap = new HashMap<>();
//        for (MonitorPoint monitor : monitorPointList) {
//            monitorMap.put(monitor.getApeId(), monitor);
//        }
//        return monitorMap;
//    }
    //    @Override
//    public RatioVo countCameraType() {
//        RatioVo ratioVo = new RatioVo();
//        List<HistogramVo> cameraTypeVoList = monitorPointMapper.selectCameraType();
//        int monitorSumOfCameraType = 0;
//        for (HistogramVo histogramVo : cameraTypeVoList) {
//            int monitorNumOfCameraType = monitorPointMapper.selectMonitorNumberOfCameraType(histogramVo.getX_axis_DictValue());
//            monitorSumOfCameraType += monitorNumOfCameraType;
//            histogramVo.setY_axis(monitorNumOfCameraType);
//        }
//        HashMap<String, Integer> map = monitorPointMapper.selectTotalMonitorCountAndOnlineMonitorCount();
//        ratioVo.setValue(monitorSumOfCameraType + "");
//        ratioVo.setData(cameraTypeVoList);
//        ratioVo.setDesc("实时更新，\n" +
//                "总数 = 球机 + 半球机 + 固定枪机 + 遥控枪机 + 卡口枪机 + 其他类型");
//        return ratioVo;
//    }

}
